home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / ply15dat.zip / SPIRAL.C < prev    next >
C/C++ Source or Header  |  1992-03-29  |  4KB  |  165 lines

  1. /* Test file to create Targa height fields for POVRay -- Alexander Enzmann */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <float.h>
  6. #include <string.h>
  7.  
  8. #ifndef M_PI
  9. #define M_PI 3.1415926535897932384626
  10. #endif
  11.  
  12. static float **height_buffer, **height_buffer2;
  13. static int GridHeight, GridWidth;
  14.  
  15. static FILE *TargaFile;
  16. static int TargaBits = 24;
  17.  
  18. static void
  19. TargaOpen(char *filename, int x, int y)
  20. {
  21.    unsigned char tgaheader[18];
  22.    if ((TargaFile = fopen(filename, "wb")) == NULL) {
  23.       printf("Failed to open Targa file: %s\n", filename);
  24.       exit(1);
  25.       }
  26.    memset(tgaheader, 0, 18);
  27.    tgaheader[2] = 2;
  28.    tgaheader[12] = (unsigned char)(x & 0xFF);
  29.    tgaheader[13] = (unsigned char)((x >> 8) & 0xFF);
  30.    tgaheader[14] = (unsigned char)(y & 0xFF);
  31.    tgaheader[15] = (unsigned char)((y >> 8) & 0xFF);
  32.    tgaheader[16] = TargaBits;
  33.    tgaheader[17] = 0x20;
  34.    fwrite(tgaheader, 18, 1, TargaFile);
  35. }
  36.  
  37. static void
  38. TargaWrite(unsigned char r, unsigned char g, unsigned char b)
  39. {
  40.    if (TargaBits == 16) {
  41.       fputc(g, TargaFile);
  42.       fputc(r, TargaFile);
  43.       }
  44.    else if (TargaBits == 24) {
  45.       fputc(b, TargaFile);
  46.       fputc(g, TargaFile);
  47.       fputc(r, TargaFile);
  48.       }
  49.    else {
  50.       fprintf(stderr, "Wrong # of bits/pixel for Targa file: %d\n",
  51.               TargaBits);
  52.       exit(1);
  53.       }
  54. }
  55.  
  56. static void
  57. TargaClose()
  58. {
  59.    fclose(TargaFile);
  60. }
  61.  
  62. static void
  63. write_height(float y)
  64. {
  65.    unsigned char r, g, b;
  66.    if (y < -127.0) y = -127.0;
  67.    if (y > 127.0) y = 127.0;
  68.    y += 128.0;
  69.    r = (unsigned char)y;
  70.    y -= (float)r;
  71.    g = (unsigned char)(256.0 * y);
  72.    b = 0;
  73.    TargaWrite(r, g, b);
  74. }
  75.  
  76. static void
  77. alloc_height_buffer(int width, int height)
  78. {
  79.    int i, j;
  80.  
  81.    height_buffer = malloc(height * sizeof(float *));
  82.    if (height_buffer == NULL) {
  83.       printf("Failed to allocate height buffer\n");
  84.       exit(1);
  85.       }
  86.    for (i=0;i<height;i++) {
  87.       height_buffer[i] = malloc(width * sizeof(float));
  88.       if (height_buffer[i] == NULL) {
  89.          printf("Failed to allocate element %d of height buffer\n", i);
  90.          exit(1);
  91.          }
  92.       for (j=0;j<width;j++)
  93.          height_buffer[i][j] = 0.0;
  94.       }
  95. }
  96.  
  97. void
  98. dump_height_buffer(int width, int height)
  99. {
  100.    int i, j;
  101.    for (i=0;i<height;i++)
  102.       for (j=0;j<width;j++)
  103.      write_height(height_buffer[i][j]);
  104. }
  105.  
  106. /* Function is: r = c * exp(a * theta) */
  107. static void
  108. make_spiral(int width, int height, int turns, float swidth)
  109. {
  110.    int i, j, k;
  111.    int x, y;
  112.    float fx, fy;
  113.    float theta, r;
  114.    float scale, offset;
  115.    int ang_steps = 8 * 360;
  116.    float delta_theta = 2.0 * M_PI / ((float)ang_steps);
  117.    float a = 1.0;
  118.    float c = 1.0;
  119.    int bump_width = 3;
  120.  
  121.    /* Figure out how to scale to get the proper # of
  122.       turns into the height field */
  123.    /* r = c * exp(a * 2.0 * M_PI * turns); */
  124.    r = a * 2.0 * M_PI * ((float)turns);
  125.    scale = 0.15 * ((float)width) / (2.0 * r);
  126.  
  127.    /* Now step through r, plopping height values down as we go */
  128.    for (i=0,theta=0.0;i<turns*ang_steps;i++,theta+=delta_theta) {
  129.       /* r = c * exp(a * theta); */
  130.       r = a * 2.0 * M_PI * theta;
  131.       fx = scale * r * cos(theta);
  132.       fy = scale * r * sin(theta);
  133.  
  134.       x = (int)fx + width/2;
  135.       y = (int)fy + height/2;
  136.  
  137.       for (j=-bump_width;j<=bump_width;j++)
  138.      for (k=-bump_width;k<=bump_width;k++)
  139.         if (x+j >= 0 && x+j < width &&
  140.             y+k >= 0 && y+k < height) {
  141.            offset = 2.0 * sqrt((float)j * (float)j + (float)k * (float)k);
  142.            height_buffer[x+j][y+k] =
  143.           (height_buffer[x+j][y+k] + (10.0 - offset)) / 2.0;
  144.            }
  145. printf("\rT: %g ", theta);
  146.       }
  147. }
  148.  
  149. void
  150. main(argc, argv)
  151.  int argc;
  152.  char **argv;
  153. {
  154.    int width    = 256;
  155.    int height   = 256;
  156.    int turns    = 5;
  157.    float swidth = 5.0;
  158.  
  159.    TargaOpen("spirhf.tga", height, width);
  160.    alloc_height_buffer(width, height);
  161.    make_spiral(width, height, turns, swidth);
  162.    dump_height_buffer(width, height);
  163.    TargaClose();
  164. }
  165.